package com.eds.log;


import com.eds.exception.BusException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 日志工具类
 *
 * @author eds
 */
@Slf4j
public class LogUtil {

    /**
     * 日志对象缓存
     */
    private static final Map<String, Logger> LOGGER_CACHE = new ConcurrentHashMap<>();

    /**
     * 获取日志对象
     *
     * @param clazz 类对象
     * @return Logger对象
     */
    public static Logger getLogger(Class<?> clazz) {
        return LOGGER_CACHE.computeIfAbsent(clazz.getName(), LoggerFactory::getLogger);
    }

    /**
     * 获取日志对象
     *
     * @param name 日志名称
     * @return Logger对象
     */
    public static Logger getLogger(String name) {
        return LOGGER_CACHE.computeIfAbsent(name, LoggerFactory::getLogger);
    }

    /**
     * 记录调试日志
     *
     * @param clazz   类对象
     * @param message 日志消息
     * @param args    参数
     */
    public static void debug(Class<?> clazz, String message, Object... args) {
        getLogger(clazz).debug(message, args);
    }

    /**
     * 记录信息日志
     *
     * @param clazz   类对象
     * @param message 日志消息
     * @param args    参数
     */
    public static void info(Class<?> clazz, String message, Object... args) {
        getLogger(clazz).info(message, args);
    }

    /**
     * 记录警告日志
     *
     * @param clazz   类对象
     * @param message 日志消息
     * @param args    参数
     */
    public static void warn(Class<?> clazz, String message, Object... args) {
        getLogger(clazz).warn(message, args);
    }

    /**
     * 记录错误日志
     *
     * @param clazz   类对象
     * @param message 日志消息
     * @param args    参数
     */
    public static void error(Class<?> clazz, String message, Object... args) {
        getLogger(clazz).error(message, args);
    }

    /**
     * 记录异常日志
     *
     * @param clazz     类对象
     * @param message   日志消息
     * @param throwable 异常对象
     */
    public static void error(Class<?> clazz, String message, Throwable throwable) {
        getLogger(clazz).error(message, throwable);
    }

    /**
     * 记录业务异常日志
     *
     * @param clazz        类对象
     * @param busException 业务异常
     */
    public static void error(Class<?> clazz, BusException busException) {
        getLogger(clazz).error("业务异常: code={}, message={}, data={}",
                busException.getCode(),
                busException.getMessage(),
                busException.getData());
    }

    /**
     * 记录方法调用日志
     *
     * @param clazz      类对象
     * @param methodName 方法名
     * @param params     参数
     */
    public static void methodCall(Class<?> clazz, String methodName, Object... params) {
        getLogger(clazz).info("方法调用: {}({})", methodName, Arrays.toString(params));
    }

    /**
     * 记录方法返回日志
     *
     * @param clazz      类对象
     * @param methodName 方法名
     * @param result     返回值
     */
    public static void methodReturn(Class<?> clazz, String methodName, Object result) {
        getLogger(clazz).info("方法返回: {}({})", methodName, result);
    }

    /**
     * 记录方法异常日志
     *
     * @param clazz      类对象
     * @param methodName 方法名
     * @param throwable  异常对象
     */
    public static void methodException(Class<?> clazz, String methodName, Throwable throwable) {
        getLogger(clazz).error("方法异常: {}({})", methodName, throwable.getMessage(), throwable);
    }

    /**
     * 记录性能日志
     *
     * @param clazz      类对象
     * @param methodName 方法名
     * @param startTime  开始时间
     */
    public static void performance(Class<?> clazz, String methodName, long startTime) {
        long costTime = System.currentTimeMillis() - startTime;
        getLogger(clazz).info("性能统计: {}({}ms)", methodName, costTime);
    }

    /**
     * 记录SQL日志
     *
     * @param clazz  类对象
     * @param sql    SQL语句
     * @param params SQL参数
     */
    public static void sql(Class<?> clazz, String sql, Object... params) {
        getLogger(clazz).debug("SQL执行: {} - {}", sql, Arrays.toString(params));
    }

    /**
     * 记录HTTP请求日志
     *
     * @param clazz  类对象
     * @param method 请求方法
     * @param url    请求URL
     * @param params 请求参数
     */
    public static void httpRequest(Class<?> clazz, String method, String url, Object... params) {
        getLogger(clazz).info("HTTP请求: {} {} - {}", method, url, Arrays.toString(params));
    }

    /**
     * 记录HTTP响应日志
     *
     * @param clazz    类对象
     * @param method   请求方法
     * @param url      请求URL
     * @param status   响应状态
     * @param response 响应数据
     */
    public static void httpResponse(Class<?> clazz, String method, String url, int status, Object response) {
        getLogger(clazz).info("HTTP响应: {} {} - {} - {}", method, url, status, response);
    }

    /**
     * 记录用户操作日志
     *
     * @param clazz     类对象
     * @param userId    用户ID
     * @param operation 操作类型
     * @param details   操作详情
     */
    public static void userOperation(Class<?> clazz, String userId, String operation, String details) {
        getLogger(clazz).info("用户操作: userId={}, operation={}, details={}", userId, operation, details);
    }

    /**
     * 记录系统事件日志
     *
     * @param clazz   类对象
     * @param event   事件类型
     * @param details 事件详情
     */
    public static void systemEvent(Class<?> clazz, String event, String details) {
        getLogger(clazz).info("系统事件: event={}, details={}", event, details);
    }

    /**
     * 记录安全日志
     *
     * @param clazz   类对象
     * @param event   安全事件
     * @param details 事件详情
     */
    public static void security(Class<?> clazz, String event, String details) {
        getLogger(clazz).warn("安全事件: event={}, details={}", event, details);
    }

    /**
     * 记录审计日志
     *
     * @param clazz     类对象
     * @param operation 操作类型
     * @param operator  操作人
     * @param target    操作对象
     * @param details   操作详情
     */
    public static void audit(Class<?> clazz, String operation, String operator, String target, String details) {
        getLogger(clazz).info("审计日志: operation={}, operator={}, target={}, details={}",
                operation, operator, target, details);
    }
}